home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
CW GUSI 1.6.4
/
src
/
GUSIMPWFile.cp
< prev
next >
Wrap
Text File
|
1995-06-21
|
8KB
|
346 lines
/*********************************************************************
Project : GUSI - Grand Unified Socket Interface
File : GUSIMPWFile.cp - MPW compatible file sockets
Author : Matthias Neeracher <neeri@iis.ee.ethz.ch>
Language : MPW C
$Log: GUSIMPWFile.cp,v $
Revision 1.2 1994/12/30 20:10:03 neeri
fRefNum is obtained lazily.
Add specialized fstat() member.
Revision 1.1 1994/08/10 00:23:40 neeri
Initial revision
*********************************************************************/
#include "GUSIFile_P.h"
#include <IOCtl.h>
#include <StdIO.h>
#include <StdLib.h>
#include <SetJmp.h>
#if defined(powerc) || defined(__powerc)
#include <FragLoad.h>
#endif
MPWDomain MPWSockets;
/*********************** Prototypes for MPW routines ***********************/
#if !defined(powerc) && !defined(__powerc)
extern "C" {
#pragma pointers_in_D0
int MPW_open(const char * name, int flags);
int MPW_close(int s);
int MPW_read(int s, char *buffer, unsigned buflen);
int MPW_write(int s, char *buffer, unsigned buflen);
int MPW_fcntl(int s, unsigned int cmd, int arg);
int MPW_ioctl(int d, unsigned int request, long *argp); /* argp is really a caddr_t */
long MPW_lseek(int fd, long offset, int whence);
int MPW_faccess(char *fileName, unsigned int cmd, long * arg);
char * MPW_getenv(const char *env);
#pragma pointers_in_A0
}
#else
static int (*MPW_open)(const char * name, int flags);
static int (*MPW_close)(int s);
static int (*MPW_read)(int s, char *buffer, unsigned buflen);
static int (*MPW_write)(int s, char *buffer, unsigned buflen);
static int (*MPW_fcntl)(int s, unsigned int cmd, int arg);
static int (*MPW_ioctl)(int d, unsigned int request, long *argp); /* argp is really a caddr_t */
static long (*MPW_lseek)(int fd, long offset, int whence);
static int (*MPW_faccess)(char *fileName, unsigned int cmd, long * arg);
static char * (*MPW_getenv)(const char *env);
static Boolean DidInitStandardLib = false;
static void InitStandardLib()
{
ConnectionID StdCLib;
SymClass symClass;
Ptr whoCares;
Str255 error;
DidInitStandardLib = true;
if (GetSharedLibrary(
StringPtr("\pStdCLib"), kPowerPCArch, kLoadLib, &StdCLib, &whoCares, error)
)
return;
if (FindSymbol(StdCLib, StringPtr("\popen"), (Ptr *) &MPW_open, &symClass))
goto failed_on_open;
if (FindSymbol(StdCLib, StringPtr("\pclose"), (Ptr *) &MPW_close, &symClass))
goto failed_on_close;
if (FindSymbol(StdCLib, StringPtr("\pread"), (Ptr *) &MPW_read, &symClass))
goto failed_on_read;
if (FindSymbol(StdCLib, StringPtr("\pwrite"), (Ptr *) &MPW_write, &symClass))
goto failed_on_write;
if (FindSymbol(StdCLib, StringPtr("\pfcntl"), (Ptr *) &MPW_fcntl, &symClass))
goto failed_on_fcntl;
if (FindSymbol(StdCLib, StringPtr("\pioctl"), (Ptr *) &MPW_ioctl, &symClass))
goto failed_on_ioctl;
if (FindSymbol(StdCLib, StringPtr("\plseek"), (Ptr *) &MPW_lseek, &symClass))
goto failed_on_lseek;
if (FindSymbol(StdCLib, StringPtr("\pfaccess"), (Ptr *) &MPW_faccess, &symClass))
goto failed_on_faccess;
if (FindSymbol(StdCLib, StringPtr("\pgetenv"), (Ptr *) &MPW_getenv, &symClass))
goto failed_on_getenv;
return;
failed_on_getenv:
MPW_getenv = nil;
failed_on_faccess:
MPW_faccess = nil;
failed_on_lseek:
MPW_lseek = nil;
failed_on_ioctl:
MPW_ioctl = nil;
failed_on_fcntl:
MPW_fcntl = nil;
failed_on_write:
MPW_write = nil;
failed_on_read:
MPW_read = nil;
failed_on_close:
MPW_close = nil;
failed_on_open:
MPW_open = nil;
}
#endif
/************************ MPWFileSocket members ************************/
#define MPW_O_RDONLY 0 /* Bits 0 and 1 are used internally */
#define MPW_O_WRONLY 1 /* Values 0..2 are historical */
#define MPW_O_RDWR 2 /* NOTE: it goes 0, 1, 2, *!* 8, 16, 32, ... */
#define MPW_O_APPEND (1<< 3) /* append (writes guaranteed at the end) */
#define MPW_O_RSRC (1<< 4) /* Open the resource fork */
#define MPW_O_ALIAS (1<< 5) /* Open alias file */
#define MPW_O_CREAT (1<< 8) /* Open with file create */
#define MPW_O_TRUNC (1<< 9) /* Open with truncation */
#define MPW_O_EXCL (1<<10) /* w/ O_CREAT: Exclusive "create-only" */
#define MPW_O_BINARY (1<<11) /* Open as a binary stream */
#define MPW_O_NRESOLVE (1<<14) /* Don't resolve any aliases */
static int TranslateOpenFlags(int mode)
{
int mpwMode;
switch (mode & 3) {
case O_RDWR:
mpwMode = MPW_O_RDWR;
break;
case O_RDONLY:
mpwMode = MPW_O_RDONLY;
break;
case O_WRONLY:
mpwMode = MPW_O_WRONLY;
break;
}
if (mode & O_APPEND)
mpwMode |= MPW_O_APPEND;
if (mode & O_CREAT)
mpwMode |= MPW_O_CREAT;
if (mode & O_EXCL)
mpwMode |= MPW_O_EXCL;
if (mode & O_TRUNC)
mpwMode |= MPW_O_TRUNC;
if (mode & O_BINARY)
mpwMode |= MPW_O_BINARY;
return mpwMode;
}
MPWFileSocket * MPWFileSocket::open(const char * name, int flags)
{
#if defined(powerc) || defined(__powerc)
if (!DidInitStandardLib)
InitStandardLib();
if (!MPW_open)
return (MPWFileSocket *) GUSI_error_nil(ENOEXEC);
#endif
int fd = MPW_open(name, TranslateOpenFlags(flags));
MPWFileSocket * sock;
if (fd == -1)
return (MPWFileSocket *) nil;
else if (sock = new MPWFileSocket(fd))
return sock;
else
return (MPWFileSocket *)GUSI_error_nil(ENOMEM);
}
MPWFileSocket * MPWFileSocket::stdopen(int fd)
{
#if defined(powerc) || defined(__powerc)
if (!DidInitStandardLib)
InitStandardLib();
if (!MPW_open)
return (MPWFileSocket *) GUSI_error_nil(ENOEXEC);
#endif
MPWFileSocket * sock;
if (sock = new MPWFileSocket(fd))
return sock;
else
return (MPWFileSocket *)GUSI_error_nil(ENOMEM);
}
MPWFileSocket::MPWFileSocket(int fd)
: FileSocket(0), fd(fd)
{
if (!MPW_open)
GUSI_error(ENOEXEC);
}
int MPWFileSocket::read(void * buffer, int buflen)
{
return MPW_read(fd, (char *) buffer, buflen);
}
int MPWFileSocket::write(void * buffer, int buflen)
{
return MPW_write(fd, (char *) buffer, buflen);
}
int MPWFileSocket::fcntl(unsigned int cmd, int arg)
{
return MPW_fcntl(fd, cmd, arg);
}
int MPWFileSocket::ioctl(unsigned int request, void *argp)
{
return MPW_ioctl(fd, request, (long *) argp);
}
long MPWFileSocket::lseek(long offset, int whence)
{
long res;
Ptr buf;
res = MPW_lseek(fd, offset, whence);
if (res != -1)
return res;
if (whence != SEEK_SET) {
res = MPW_lseek(fd, 0, whence);
if (res == -1)
return res;
offset += res;
}
res = MPW_lseek(fd, 0, SEEK_END);
buf = NewPtrClear(1024);
while (offset >= res + 1024)
if (MPW_write(fd, buf, 1024) == -1)
return -1;
else
res += 1024;
if (offset > res && MPW_write(fd, buf, unsigned(offset-res)) == -1)
return -1;
return offset;
}
int MPWFileSocket::ftruncate(long offset)
{
if (lseek(offset, SEEK_SET) == -1)
return -1;
if (MPW_ioctl(fd, FIOSETEOF, (long *) offset) == -1)
return -1;
return 0;
}
int MPWFileSocket::fstat(struct stat * buf)
{
short fRef;
if (fRefNum || MPW_ioctl(fd, FIOREFNUM, (long *) &fRef) != -1) {
if (!fRefNum)
SetFRefNum(fRef);
return FileSocket::fstat(buf);
} else {
// Pseudofile
buf->st_dev = 0;
buf->st_ino = 0;
buf->st_mode = S_IFCHR | 0666;
buf->st_nlink = 1;
buf->st_uid = 0;
buf->st_gid = 0;
buf->st_rdev = 0;
buf->st_size = 1;
buf->st_atime = time(NULL);
buf->st_mtime = time(NULL);
buf->st_ctime = time(NULL);
buf->st_blksize = 1;
buf->st_blocks = 1;
return 0;
}
}
int MPWFileSocket::isatty()
{
short fRef;
return MPW_ioctl(fd, FIOREFNUM, (long *) &fRef) == -1;
}
MPWFileSocket::~MPWFileSocket()
{
MPW_close(fd);
}
char *getenv(const char * name)
{
#ifdef powerc
if (!DidInitStandardLib)
InitStandardLib();
if (!MPW_getenv)
return NULL;
#endif
return MPW_getenv(name);
}
/********************* PPCSocketDomain member **********************/
MPWFileSocket * (*MPWDomain::open)(const char * name, int flags) = nil;
MPWFileSocket * (*MPWDomain::stdopen)(int fd) = nil;
MPWDomain::MPWDomain()
: SocketDomain(AF_UNSPEC)
{
#ifdef powerc
extern jmp_buf __program_exit, __target_for_exit;
memcpy(__program_exit, __target_for_exit, 70*sizeof(long *));
#endif
open = MPWFileSocket::open;
stdopen = MPWFileSocket::stdopen;
}
extern "C" void RemoveConsole(void)
{
}
extern "C" void _coreIOExit(void)
{
}